home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks97 / WarriorsProgress.sit / Warrior’s Progress / source code / Source / Libraries / Files / FileLocation.cp < prev    next >
Text File  |  1997-06-28  |  8KB  |  369 lines

  1. // FileLocation.cp
  2.  
  3. #ifndef FileLocation_h
  4. #include "FileLocation.h"
  5. #endif
  6. #ifndef PString_h
  7. #include "PString.h"
  8. #endif
  9. #ifndef Str_h
  10. #include "Str.h"
  11. #endif
  12. #ifndef Application_h
  13. #include "Application.h"
  14. #endif
  15. #ifndef ProcessInfo_h
  16. #include "ProcessInfo.h"
  17. #endif
  18. #ifndef FileNotFoundError_h
  19. #include "FileNotFoundError.h"
  20. #endif
  21. #ifndef DirectoryNotFoundError_h
  22. #include "DirectoryNotFoundError.h"
  23. #endif
  24. #ifndef DuplicateFileError_h
  25. #include "DuplicateFileError.h"
  26. #endif
  27. #ifndef DirectoryFullError_h
  28. #include "DirectoryFullError.h"
  29. #endif
  30. #ifndef DiskFullError_h
  31. #include "DiskFullError.h"
  32. #endif
  33. #ifndef HardwareVolumeLockError_h
  34. #include "HardwareVolumeLockError.h"
  35. #endif
  36. #ifndef SoftwareVolumeLockError_h
  37. #include "SoftwareVolumeLockError.h"
  38. #endif
  39. #ifndef FileLockError_h
  40. #include "FileLockError.h"
  41. #endif
  42. #ifndef FileBusyError_h
  43. #include "FileBusyError.h"
  44. #endif
  45. #ifndef FilePermissionError_h
  46. #include "FilePermissionError.h"
  47. #endif
  48. #ifndef CatInfo_h
  49. #include "CatInfo.h"
  50. #endif
  51.  
  52. FileLocation::FileLocation()
  53.   {
  54.     vRefNum = 0;
  55.     parID = 0;
  56.     name[0] = 0;
  57.   }
  58.  
  59. FileLocation::FileLocation( Directory directory,
  60.                                      ConstPString theName )
  61.   {
  62.     name[0] = 0;
  63.     SetParent( directory );
  64.     SetName( theName );
  65.   }
  66.  
  67. FileLocation::FileLocation( Directory directory )
  68.   {
  69.     name[0] = 0;
  70.     CatInfo info( directory );
  71.     *this = info.Location();
  72.   }
  73.  
  74. void FileLocation::Set( Directory directory,
  75.                                 ConstPString theName )
  76.   {
  77.     SetParent( directory );
  78.     SetName( theName );
  79.   }
  80.  
  81. void FileLocation::operator=( Directory directory )
  82.   {
  83.     CatInfo info( directory );
  84.     *this = info.Location();
  85.   }
  86.  
  87. void FileLocation::SetName( ConstPString newName )
  88.   {
  89.     PString( Data( name, sizeof(name) ) ) = newName;
  90.   }
  91.  
  92. void FileLocation::SetName( ConstPString base, uint32 number )
  93.   {
  94.     String31 newName;
  95.     String255 numeral;
  96.     
  97.     NumToString( number, numeral );
  98.     
  99.     if ( base.Length() + numeral.Length() + 1 <= 31 )
  100.       {
  101.         newName.SetLength( base.Length() + numeral.Length() + 1 );
  102.         newName.Head( base.Length() ) << base;
  103.         newName[ base.Length() ] = ' ';
  104.         newName.Tail( base.Length() + 1 ) << numeral;
  105.       }
  106.      else if ( base.Length() + numeral.Length() <= 31 )
  107.       {
  108.         newName.SetLength( base.Length() + numeral.Length() );
  109.         newName.Head( base.Length() ) << base;
  110.         newName.Tail( base.Length() ) << numeral;
  111.       }
  112.      else
  113.       {
  114.         uint32 baseAmount = 31 - numeral.Length() - 1;
  115.         static const uint8 elipsis = 0xc9;
  116.  
  117.         newName.SetLength( 31 );
  118.         newName.Head( baseAmount ) << base;
  119.         newName[ baseAmount ] = elipsis;
  120.         newName.Tail( baseAmount + 1 ) << numeral;
  121.       }
  122.     
  123.     SetName( newName );
  124.   }
  125.  
  126. Directory FileLocation::AsDirectory() const
  127.   {
  128.     return CatInfo( *this ).AsDirectory();
  129.   }
  130.  
  131. bool FileLocation::NameIsValid() const
  132.   {
  133.     ConstPString name( this->name );
  134.     
  135.     if ( name.Length() == 0 )
  136.         return false;
  137.     
  138.     if ( name.Length() > 31 )
  139.         return false;
  140.     
  141.     if ( name[0] == '.' )
  142.         return false;
  143.     
  144.     for ( uint32 i = 0; i < name.Length(); i++ )
  145.         if ( name[i] == ':' )
  146.             return false;
  147.     
  148.     return true;
  149.   }
  150.  
  151. void FileLocation::SetToValidName( ConstPString start )
  152.   {
  153.     SetName( start );
  154.     SetToValidName();
  155.   }
  156.  
  157. void FileLocation::SetToValidName()
  158.   {
  159.     PString name( Data( this->name, sizeof(this->name) ) );
  160.     static const uint8 bullet = 0xA5;
  161.     
  162.     if ( name.Length() == 0 )
  163.       {
  164.         name.SetLength( 1 );
  165.         name[0] = bullet;
  166.       }
  167.     
  168.     if ( name.Length() > 31 )
  169.         name.SetLength( 31 );
  170.     
  171.     if ( name[0] == '.' )
  172.         name[0] = bullet;
  173.     
  174.     for ( uint32 i = 0; i < name.Length(); i++ )
  175.         if ( name[i] == ':' )
  176.             name[i] = '/';
  177.     
  178.     Assert( NameIsValid() );
  179.   }
  180.  
  181. bool FileLocation::operator==( const FileLocation& r ) const
  182.   {
  183.     return vRefNum == r.vRefNum
  184.          && parID == r.parID
  185.          && EqualString( name, r.name, false, true );
  186.   }
  187.  
  188. void FileLocation::ThrowError( OSErr error )
  189.   {
  190.     if ( error == noErr )
  191.         return;
  192.     
  193.     switch ( error )
  194.       {
  195.         case fnfErr:                throw FileNotFoundError( error );
  196.         case dirNFErr:                throw DirectoryNotFoundError( error );
  197.         case dupFNErr:                throw DuplicateFileError( error );
  198.         case dirFulErr:            throw DirectoryFullError( error );
  199.         case dskFulErr:            throw DiskFullError( error );
  200.         case wPrErr:                throw HardwareVolumeLockError( error );
  201.         case vLckdErr:                throw SoftwareVolumeLockError( error );
  202.         case fLckdErr:                throw FileLockError( error );
  203.         case fBsyErr:                throw FileBusyError( error );
  204.         case afpAccessDenied:    throw FilePermissionError( error );
  205.       }
  206.     
  207.     throw FileError( error );
  208.   }
  209.  
  210. bool FileLocation::Exists() const
  211.   {
  212.     Assert( NameIsValid() );
  213.     
  214.     String255 localName( name );
  215.     CInfoPBRec info;
  216.     info.hFileInfo.ioCompletion = 0;
  217.     info.hFileInfo.ioVRefNum = vRefNum;
  218.     info.hFileInfo.ioDirID = parID;
  219.     info.hFileInfo.ioNamePtr = localName;
  220.     info.hFileInfo.ioFVersNum = 0;
  221.     info.hFileInfo.ioFDirIndex = 0;
  222.     
  223.     OSErr error = PBGetCatInfoSync( &info );
  224.     
  225.     if ( error != noErr && error != fnfErr )
  226.         ThrowError( error );
  227.     
  228.     return error == noErr;
  229.   }
  230.  
  231. void FileLocation::FindUnusedName()
  232.   {
  233.     if ( !Exists() )
  234.         return;
  235.         
  236.     String31 baseName( name );
  237.     uint32 number = 1;
  238.     
  239.     do
  240.       {
  241.         Assert( number < maxuint32 );
  242.         SetName( baseName, ++number );
  243.       }
  244.      while ( Exists() );
  245.   }
  246.  
  247. void FileLocation::CreateFile( FileType type,
  248.                                          FileSignature signature,
  249.                                          ScriptID script ) const
  250.   {
  251.     Assert( NameIsValid() );
  252.      ThrowError( FSpCreate( this,
  253.                                    signature.Signature(),
  254.                                    type.Type(),
  255.                                    script.ID() ) );
  256.   }
  257.  
  258. void FileLocation::CreateFile( FileType type,
  259.                                          ScriptID script ) const
  260.   {
  261.     CreateFile( type,
  262.                     ProcessInfo::Application().Signature(),
  263.                     script );
  264.   }
  265.  
  266. Directory FileLocation::CreateDirectory( ScriptID script ) const
  267.   {
  268.     Assert( NameIsValid() );
  269.     int32 directory;
  270.      ThrowError( FSpDirCreate( this, script.ID(), &directory ) );
  271.      return Directory( Volume(), DirectoryID::Make( directory ) );
  272.   }
  273.  
  274. void FileLocation::Delete() const
  275.   {
  276.     Assert( NameIsValid() );
  277.      ThrowError( FSpDelete( this ) );
  278.   }
  279.  
  280. void FileLocation::Lock() const
  281.   {
  282.     Assert( NameIsValid() );
  283.      ThrowError( FSpSetFLock( this ) );
  284.   }
  285.  
  286. void FileLocation::Unlock() const
  287.   {
  288.     Assert( NameIsValid() );
  289.      ThrowError( FSpRstFLock( this ) );
  290.   }
  291.  
  292. void FileLocation::MoveFrom( const FileLocation& source ) const
  293.   {
  294.     Assert( Volume() == source.Volume() );
  295.     Assert( *this != source );
  296.     Assert( NameIsValid() );
  297.     Assert( source.Exists() );
  298.     Assert( !Exists() );
  299.     
  300.     if ( ParentID() == source.ParentID() )
  301.          ThrowError( FSpRename( &source, name ) );
  302.       else
  303.          ThrowError( FSpCatMove( &source, this ) );
  304.   }
  305.  
  306. void FileLocation::SwapWith( const FileLocation& source ) const
  307.   {
  308.     Assert( Volume() == source.Volume() );
  309.     Assert( *this != source );
  310.     Assert( NameIsValid() );
  311.     Assert( source.Exists() );
  312.     Assert( Exists() );
  313.     
  314.      ThrowError( FSpExchangeFiles( this, &source ) );
  315.   }
  316.  
  317. void FileLocation::Up()
  318.   {
  319.     Assert( !IsRoot() );
  320.     if ( IsRoot() )
  321.         ThrowError( dirNFErr );
  322.     
  323.     CatInfo info( Parent() );
  324.     *this = info.Location();
  325.   }
  326.  
  327. void FileLocation::Down( ConstPString child )
  328.   {
  329.     SetParent( AsDirectory() );
  330.     SetName( child );
  331.   }
  332.  
  333. void FileLocation::Sideways( ConstPString sibling )
  334.   {
  335.     SetName( sibling );
  336.   }
  337.  
  338. FileLocation FileLocation::Child( ConstPString child ) const
  339.   {
  340.     return FileLocation( AsDirectory(), child );
  341.   }
  342.  
  343. FileLocation FileLocation::Sibling( ConstPString sibling ) const
  344.   {
  345.     return FileLocation( Parent(), sibling );
  346.   }
  347.  
  348. DirectoryID FileLocation::GetDirectoryID() const
  349.   {
  350.     CatInfo info( *this );
  351.  
  352.     Assert( info.IsDirectory() );
  353.     if ( !info.IsDirectory() )
  354.         ThrowError( afpObjectTypeErr );
  355.  
  356.     return info.Directory().ID();
  357.   }
  358.  
  359. FileID FileLocation::GetFileID() const
  360.   {
  361.     CatInfo info( *this );
  362.     
  363.     Assert( !info.IsDirectory() );
  364.     if ( info.IsDirectory() )
  365.         ThrowError( notAFileErr );
  366.     
  367.     return info.File().ID();
  368.   }
  369.